home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / mmv10.zip / MMVPATCH.C < prev    next >
Text File  |  1989-11-22  |  6KB  |  253 lines

  1. /*
  2.     mmvpatch 1.0
  3.     Copyright (c) 1989 by Vladimir Lanin.
  4.     This program may be freely used and copied on a non-commercial basis.
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <io.h>
  9. #include <fcntl.h>
  10. #include <string.h>
  11. #include <ctype.h>
  12. #include <dir.h>
  13. #include <dos.h>
  14. #include <process.h>
  15.  
  16. #define PATCHOFF 0x6C04
  17.  
  18. #define CLUSTOFF1 19
  19. #define CLUSTOFF2 15
  20. #define DRIVEOFF1 0
  21. #define TEMPLOFF1 1
  22. #define ATTROFF1 12
  23. #define DRIVEOFF2 1
  24. #define TEMPLOFF2 2
  25. #define ATTROFF2 0
  26.  
  27. #define NORMCOPY 0x002
  28. #define OVERWRITE 0x004
  29. #define NORMMOVE 0x008
  30. #define XMOVE 0x010
  31. #define DIRMOVE 0x020
  32. #define NORMAPPEND 0x040
  33. #define ZAPPEND 0x080
  34.  
  35. static void checkid(char *n, int *i1, int *i2, int *d1, int *d2);
  36. static void quit(void);
  37. static int curdrive;
  38.  
  39. static struct {
  40.     char ph_banner[30];
  41.     char ph_name[9];
  42.     int ph_dfltop;
  43.     int ph_safeid;
  44.     int ph_clustoff;
  45.     int ph_driveoff;
  46.     int ph_drivea;
  47. } patch;
  48.  
  49. int main(int argc, char *(argv[]))
  50. {
  51.     int binary;
  52.     char *popname;
  53.     char buf[80];
  54.     int i;
  55.     static char opnames[] = "xmrcoaz";
  56.     static int ops[] =
  57.         {XMOVE, NORMMOVE, DIRMOVE, NORMCOPY, OVERWRITE, NORMAPPEND, ZAPPEND};
  58.     static char dirname[] = "$$tmpdir.tmp";
  59.     int ci1, ci2, cd1, cd2;
  60.     int si1, si2, sd1, sd2;
  61.     int ni1, ni2, nd1, nd2;
  62.     int ai1, ai2, ad1, ad2;
  63.     int d1, d2, i1, i2;
  64.  
  65.     if (argc == 1)
  66.         argv[1] = "mmv.exe";
  67.     else if (argc > 2) {
  68.         fprintf(stderr,
  69.             "Usage: mmvpatch [mmv_copy]\n");
  70.         quit();
  71.     }
  72.  
  73.     if ((binary = open(argv[1], O_RDWR | O_BINARY)) < 0) {
  74.         fprintf(stderr, "%s: file not found.\n", argv[1]);
  75.         quit();
  76.     }
  77.  
  78.     if (
  79.         lseek(binary, PATCHOFF, 0) != PATCHOFF ||
  80.         read(binary, &patch, sizeof(patch)) != sizeof(patch) ||
  81.         strcmp(patch.ph_banner, "mmv 1.0 patchable flags")
  82.     ) {
  83.         fprintf(stderr, "Can't find patch area in %s.\n", argv[1]);
  84.         quit();
  85.     }
  86.  
  87.     fnsplit(argv[1], NULL, NULL, patch.ph_name, NULL);
  88.  
  89.     for (i = 0; i < sizeof(ops) && ops[i] != patch.ph_dfltop; i++)
  90.         ;
  91.     if (i > sizeof(ops)) {
  92.         i = 0;
  93.         patch.ph_dfltop = ops[i];
  94.     }
  95.     do {
  96.         printf("Enter default task option [x|m|r|c|o|a|z|CR=%c]: ",
  97.             opnames[i]);
  98.         gets(buf);
  99.         *buf = tolower(*buf);
  100.     } while ((popname = strchr(opnames, *buf)) == NULL);
  101.     if ((i = popname - opnames) < sizeof(opnames) - 1)
  102.         patch.ph_dfltop = ops[i];
  103.  
  104.     curdrive = getdisk();
  105.     strcpy(buf, "*.*");
  106.     checkid(buf, &ci1, &ci2, &cd1, &cd2);
  107.  
  108.     if (mkdir(dirname)) {
  109.         fprintf(stderr, "Couldn't mkdir %s.\n", dirname);
  110.         quit();
  111.     }
  112.     strcpy(buf, dirname);
  113.     strcat(buf, "/*.*");
  114.     checkid(buf, &si1, &si2, &sd1, &sd2);
  115.     strcpy(buf, dirname);
  116.     strcat(buf, "/../*.*");
  117.     checkid(buf, &ni1, &ni2, &nd1, &nd2);
  118.     rmdir(dirname);
  119.  
  120.     fprintf(stderr,
  121.         "Put a formatted disk in drive A (no data will be lost).\n"
  122.         "Hit any key when ready... ");
  123.     getchar();
  124.  
  125.     strcpy(buf, "a:/");
  126.     strcat(buf, dirname);
  127.     if (mkdir(buf)) {
  128.         fprintf(stderr, "Couldn't mkdir %s.\n", buf);
  129.         quit();
  130.     }
  131.     checkid("a:/*.*", &ai1, &ai2, &ad1, &ad2);
  132.     rmdir(buf);
  133.  
  134.     d1 = (
  135.         cd1 != -1 &&
  136.         cd1 == sd1 &&
  137.         sd1 == nd1 &&
  138.         ad1 != -1 &&
  139.         cd1 - curdrive == ad1
  140.     );
  141.     d2 = (
  142.         cd2 != -1 &&
  143.         cd2 == sd2 &&
  144.         sd2 == nd2 &&
  145.         ad2 != -1 &&
  146.         cd2 - curdrive == ad2
  147.     );
  148.  
  149.     i1 = (
  150.         ci1 == ni1 &&
  151.         ci1 != si1 &&
  152.         si1 != 0 &&
  153.         ai1 == 0
  154.     );
  155.     i2 = (
  156.         ci2 == ni2 &&
  157.         ci2 != si2 &&
  158.         si2 != 0 &&
  159.         ai2 == 0
  160.     );
  161.  
  162.     if (!(d1 || d2) && !(i1 || i2))
  163.         patch.ph_safeid = 1;
  164.     else {
  165.         patch.ph_safeid = 0;
  166.         if (d1) {
  167.             patch.ph_driveoff = DRIVEOFF1;
  168.             patch.ph_drivea = ad1;
  169.         }
  170.         else {
  171.             patch.ph_driveoff = DRIVEOFF2;
  172.             patch.ph_drivea = ad2;
  173.         }
  174.         if (i1)
  175.             patch.ph_clustoff = CLUSTOFF1;
  176.         else
  177.             patch.ph_clustoff = CLUSTOFF2;
  178.     }
  179.  
  180.     if (patch.ph_safeid)
  181.         printf("Must use slow directory identification method.\n");
  182.     else {
  183.         printf(
  184.             "The fast dir-id method works.\n"
  185.             "(clustoff == %d, driveoff == %d, drivea == %d).\n",
  186.             patch.ph_clustoff, patch.ph_driveoff, patch.ph_drivea);
  187.         do {
  188.             printf("Do you wish to use it [y/n]? ");
  189.             gets(buf);
  190.             *buf = tolower(*buf);
  191.         } while (*buf != 'y' && *buf != 'n');
  192.         if (*buf == 'n')
  193.             patch.ph_safeid = 1;
  194.     }
  195.  
  196.     do {
  197.         printf("Is all of the above satisfactory [y/n]? ");
  198.         gets(buf);
  199.         *buf = tolower(*buf);
  200.     } while (*buf != 'y' && *buf != 'n');
  201.     if (*buf == 'n')
  202.         printf("Ok, will not write patch.\n");
  203.     else if (
  204.         lseek(binary, PATCHOFF, 0) != PATCHOFF ||
  205.         write(binary, &patch, sizeof(patch)) != sizeof(patch) ||
  206.         close(binary)
  207.     ) {
  208.         fprintf(stderr, "Error writing patch to %s.\n", argv[1]);
  209.         quit();
  210.     }
  211.     return(0);
  212. }
  213.  
  214.  
  215. static void checkid(char *n, int *id1, int *id2, int *d1, int *d2)
  216. {
  217.     struct ffblk ff;
  218.  
  219.     *(int *)(&(ff.ff_reserved[CLUSTOFF1])) = 0;
  220.     *(int *)(&(ff.ff_reserved[CLUSTOFF2])) = 0;
  221.     ff.ff_reserved[ATTROFF1] = -1;
  222.     ff.ff_reserved[TEMPLOFF1] = -1;
  223.     ff.ff_reserved[DRIVEOFF1] = -1;
  224.     ff.ff_reserved[ATTROFF2] = -1;
  225.     ff.ff_reserved[TEMPLOFF2] = -1;
  226.     ff.ff_reserved[DRIVEOFF2] = -1;
  227.     if (findfirst(n, &ff, FA_DIREC | FA_HIDDEN | FA_SYSTEM)) {
  228.         fprintf(stderr, "Can't findfirst %s.\n", n);
  229.         quit();
  230.     }
  231.     *id1 = *(int *)(&(ff.ff_reserved[CLUSTOFF1]));
  232.     *id2 = *(int *)(&(ff.ff_reserved[CLUSTOFF2]));
  233.     *d1 = ff.ff_reserved[DRIVEOFF1];
  234.     *d2 = ff.ff_reserved[DRIVEOFF2];
  235.     if (
  236.         ff.ff_reserved[ATTROFF1] != (FA_DIREC | FA_HIDDEN | FA_SYSTEM) ||
  237.         ff.ff_reserved[TEMPLOFF1] != '?'
  238.     )
  239.         *d1 = -1;
  240.     if (
  241.         ff.ff_reserved[ATTROFF2] != (FA_DIREC | FA_HIDDEN | FA_SYSTEM) ||
  242.         ff.ff_reserved[TEMPLOFF2] != '?'
  243.     )
  244.         *d2 = -1;
  245. }
  246.  
  247.  
  248. static void quit(void)
  249. {
  250.     fprintf(stderr, "Aborting. No updates made.\n");
  251.     exit(1);
  252. }
  253.